#include <iostream>
#include <map>
#include <vector>



#ifndef __xiong_iothead
#define __xiong_iothead 

#include "Poco/Net/SocketNotification.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/Socket.h"
#include "Poco/Observer.h"
#include "Poco/NObserver.h"
#include "Poco/Exception.h"
#include "Poco/Thread.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/Runnable.h"
#include "Poco/AutoPtr.h"
#include "Poco/Mutex.h"
#include "Poco/Net/SocketReactor.h"
#include "Poco/RefCountedObject.h"


#include "Reactor.h"
#include "sockethandler.h"
#include "socketlist.h"
#include "ReactorRuner.h"


using Poco::Net::ReadableNotification;
using Poco::Net::ShutdownNotification;
using Poco::Net::ServerSocket;
using Poco::Net::Socket;
using Poco::Net::SocketReactor;
using Poco::Net::StreamSocket;
using Poco::Observer;
using Poco::NObserver;
using Poco::AutoPtr;
using Poco::FastMutex;
using Poco::Thread;
using Poco::Util::ServerApplication;
using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;
using Poco::Runnable;


class Iothread : public Runnable,ReactorRuner
{
public:
    Iothread(Poco::UInt16 port=8099):
        _stop(false)
    {
        svs.bind(port);
        svs.listen(60);
        reactor.setRuner(this);
        reactor.addEventHandler(svs, Poco::Observer<Iothread, ReadableNotification>(*this, &Iothread::onAccept));
    }

    void onIdle()
    {
        process_close_socket();
    }

    void onBusy()
    {
        process_close_socket();
    }

    void onTimeout()
{
    //std::cout << "iothread timeout" << std::endl;
}
    
    ~Iothread()
    {
        reactor.stop();
    }

    void onAccept(ReadableNotification* pNotification)
    {
        
        pNotification->release();
        StreamSocket sock = svs.acceptConnection();
        handlerPtr echohandler;
        echohandler = new EchoServiceHandler(sock);
        _socketMap[sock] = echohandler;
        reactor.addEventHandler(sock, NObserver<EchoServiceHandler, ReadableNotification>(*_socketMap[sock], &EchoServiceHandler::onReadable));
        reactor.addEventHandler(sock, NObserver<EchoServiceHandler, ShutdownNotification>(*_socketMap[sock], &EchoServiceHandler::onShutdown));

    }

    void run()
    {
        reactor.run();
    }

    void process_close_socket()
    {
        std::vector<Socket> closelist;
        socketcloselist.clone(closelist);
        for (std::vector<Socket>::iterator it = closelist.begin() ; it != closelist.end(); ++it)
        {
            socketMap::iterator mapit = _socketMap.find(*it);
            if (mapit != _socketMap.end())
            {
        reactor.removeEventHandler(*it, NObserver<EchoServiceHandler, ReadableNotification>(*_socketMap[*it], &EchoServiceHandler::onReadable));
        reactor.removeEventHandler(*it, NObserver<EchoServiceHandler, ShutdownNotification>(*_socketMap[*it], &EchoServiceHandler::onShutdown));
                _socketMap.erase(mapit);
            }
        }
    }

    void test(){

        std::cout << "iothread test" << std::endl;

    }

private:
    ServerSocket svs;
    Reactor reactor; 
    typedef AutoPtr<EchoServiceHandler> handlerPtr;
    typedef std::map<Socket, handlerPtr> socketMap;
    //typedef std::map<int, handlerPtr> socketMap;
    socketMap _socketMap;
    bool _stop;
};


#endif
